/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.diagram.usecase.helper;

import java.util.Iterator;

import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.PackageableElement;
import org.eclipse.uml2.uml.UMLFactory;

import com.cea.papyrus.core.helper.NodeHelper;
import com.cea.papyrus.core.utils.Debug;
import com.cea.papyrus.diagram.usecase.Activator;
import com.cea.papyrus.diagram.usecase.preference.UseCaseDiagramPreferenceConstants;
import com.cea.papyrus.diagraminterchange2.di2.Di2Factory;
import com.cea.papyrus.diagraminterchange2.di2.Diagram;
import com.cea.papyrus.diagraminterchange2.di2.DiagramElement;
import com.cea.papyrus.diagraminterchange2.di2.GraphElement;
import com.cea.papyrus.diagraminterchange2.di2.GraphNode;
import com.cea.papyrus.diagraminterchange2.di2.Property;
import com.cea.papyrus.diagraminterchange2.di2.Uml1SemanticModelBridge;

/**
 * Defines management of actors.
 * 
 * @author Gilles Cannenterre
 * @since 9 oct. 06
 */
public class NodeActorHelper extends NodeHelper {
	
	/**
	 * The Constant ACTOR_CLASSIFIER_FORM.
	 */
	public final static String ACTOR_CLASSIFIER_FORM = "ActorClassifierForm";

	/**
	 * The Constant ACTOR_STICKMAN_FORM.
	 */
	public final static String ACTOR_STICKMAN_FORM = "ActorStickmanForm";

	/**
	 * The channel.
	 */
	private int channel = 203;
	
	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.factories.NodeFactory#canCreateGraphElement(com.cea.papyrus.diagraminterchange2.di2.GraphElement)
	 */
	/**
	 * 
	 * 
	 * @param parent 
	 * 
	 * @return 
	 */
	@Override
	public boolean canCreateGraphElement(GraphElement parent) {
		if(parent instanceof Diagram) {
			return true; //this a diagram
		} else if (parent.getSemanticModel()!=null){
			Element parentElt= ((Uml1SemanticModelBridge)parent.getSemanticModel()).getElement();
			if(parentElt!=null){
				return canCreateUMLElement(parentElt);
			}		
		}
		return false;
	}

	
	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.factories.INodeFactory#createGraphNode()
	 */
	/**
	 * 
	 * 
	 * @param umlChild 
	 * @param size 
	 * @param location 
	 * @param parent 
	 * 
	 * @return 
	 */
	public GraphNode createGraphElement(Element umlChild, GraphElement parent, Point location, Dimension size){
		GraphNode gn= super.createGraphElement(umlChild, parent, location, size);
		//Create label for names
		NodeHelper nh= new NodeHelper();
		GraphNode node;
		if (location != null){
			node = nh.createGraphElement(null,null, new Point(location.x+30,location.y+gn.getSize().height+5), null);
		} else {
			node = nh.createGraphElement(null,null, new Point(50,20+gn.getSize().height+5), null);
		}
		node.setSemanticParent(gn);
	    node.setContainer(parent);
	    return gn;
	}
	
	/**
	 * 
	 * 
	 * @param child 
	 * @param parent 
	 * 
	 * @return 
	 */
	public boolean undoCreateGraphElement(GraphElement child, GraphElement parent){
		child.setSemanticParent(null);
		child.eAdapters().clear();
		Iterator<DiagramElement> itchild=child.getSemanticChild().iterator();
		for(int i=0; i<child.getSemanticChild().size();){
			GraphElement subchild=(GraphElement)child.getSemanticChild().get(i);
			subchild.eAdapters().clear();
			subchild.setSemanticParent(null);
			subchild.getContainer().getContained().remove(subchild);
		}
		child.getContainer().getContained().remove(child);
		return true;
	}

	
	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.factories.NodeFactory#createUMLElement(java.lang.String, org.eclipse.uml2.uml.Element)
	 */
	/**
	 * 
	 * 
	 * @param name 
	 * @param parent 
	 * 
	 * @return 
	 */
	@Override
	public Element createUMLElement(String name, Element parent) {
		Debug.debug(this,"createElement(String,Element)", channel);
		org.eclipse.uml2.uml.Actor aActor=UMLFactory.eINSTANCE.createActor();
		aActor.setName(name);
		((Package)parent.getNearestPackage()).getPackagedElements().add(aActor);
		return aActor;
	}

	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.factories.NodeFactory#addUMLElement(org.eclipse.uml2.uml.Element, org.eclipse.uml2.uml.Element)
	 */
	/**
	 * 
	 * 
	 * @param element 
	 * @param umlParent 
	 * 
	 * @return 
	 */
	@Override
	public boolean addUMLElement(Element element, Element umlParent) {
		if(umlParent instanceof Package) {
			return ((Package)umlParent).getPackagedElements().add((PackageableElement)element);
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.factories.NodeFactory#canCreateUMLElement(org.eclipse.uml2.uml.Element)
	 */
	/**
	 * 
	 * 
	 * @param umlParent 
	 * 
	 * @return 
	 */
	@Override
	public boolean canCreateUMLElement(Element umlParent) {
		if(umlParent instanceof Package) {
			return true;
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.factories.NodeFactory#removeUMLElement(org.eclipse.uml2.uml.Element, org.eclipse.uml2.uml.Element)
	 */
	/**
	 * 
	 * 
	 * @param element 
	 * @param umlParent 
	 * 
	 * @return 
	 */
	@Override
	public boolean removeUMLElement(Element element, Element umlParent) {
		if(umlParent instanceof Package) {
			return ((Package)umlParent).getPackagedElements().remove(element);
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.factories.NodeFactory#setGraphElementPreferences(com.cea.papyrus.diagraminterchange2.di2.GraphElement)
	 */
	/**
	 * 
	 * 
	 * @param graphElement 
	 */
	@Override
	public void setGraphElementPreferences(GraphElement graphElement) {	
		// Get the preference store
		IPreferenceStore store = Activator.getDefault().getPreferenceStore();
		
		// Set colors and font
		graphElement.setBackgroundColor(UseCaseDiagramPreferenceConstants.getPreferenceActorBackgroundColor(store));
		graphElement.setBorderColor(UseCaseDiagramPreferenceConstants.getPreferenceActorBorderColor(store));
		graphElement.setFontColor(UseCaseDiagramPreferenceConstants.getPreferenceActorFontColor(store));
		FontData[] fontdata = UseCaseDiagramPreferenceConstants.getPreferenceActorFont(store);
		if (fontdata.length>0){
			graphElement.setFontFamily(fontdata[0].getName());
			graphElement.setFontSize(fontdata[0].getHeight());
		}
		
		// Set appearance
		Property property = graphElement.getProperty(NodeHelper.NODE_FIGURE_APPEARANCE);
		if (property == null){
			// Create a property for this graph node to hold appearance
			property=Di2Factory.eINSTANCE.createProperty();
			property.setKey(NodeHelper.NODE_FIGURE_APPEARANCE);
			property.setValue(UseCaseDiagramPreferenceConstants.getPreferenceActorAppearance(store));		
			graphElement.getProperty().add(property);
		} else{
			property.setValue(UseCaseDiagramPreferenceConstants.getPreferenceActorAppearance(store));	
		}
	}
	
	/* (non-Javadoc)
	 * @see com.cea.papyrus.common.factories.NodeFactory#getBaseString()
	 */
	/**
	 * 
	 * 
	 * @return 
	 */
	@Override
	public String getBaseString() {
		return "Actor_"; //$NON-NLS-1$
	}


	/**
	 * Gets the graph node size.
	 * 
	 * @return the graph node size
	 */
	public Dimension getGraphNodeSize() {
		return new Dimension(60,90);
	}
}